package main

import (
	"fmt"
)

func doWork(id int, w worker) {
	for n := range w.in {
		fmt.Printf("Worker %d received %c\n", id, n)
		go func() {
			w.done <- true
			// 作为终止规则，当外层for循环终止时，这个goroutine也终止，此时不再给done传入true
			// 最下方for循环跳出
			// 如果没有done时则in会不断接受空串而造成死锁
			// 因为有两组数据写入，如果可能一组数据写完后退出了最下面的主控
			// 只收到了一个空值（退出信号）就所有的退出了而另外一组数据还未处理完毕
		}()

	}
}

type worker struct {
	in   chan int
	done chan bool
}

func createWorker(id int) worker {
	w := worker{
		in:   make(chan int),
		done: make(chan bool),
	}
	go doWork(id, w)
	return w
}

func chanDemo() {
	var workers [10]worker

	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i)
	}

	for i, worker := range workers {
		worker.in <- 'a' + i
	}

	for i, worker := range workers {
		worker.in <- 'A' + i
	}
	// wit for all of them
	for _, worker := range workers {
		// 退出主程序的退出所有
		n := <-worker.done
		m := <-worker.done
		fmt.Println(n, m)
	}
}

func main() {
	chanDemo()
}
